///*
// * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
// *
// * Licensed under the Apache License, Version 2.0 (the "License"); you may not
// * use this file except in compliance with the License. You may obtain a copy
// * of the License at
// *
// *   http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// * License for the specific language governing permissions and limitations
// * under the License.
// *
// */
//package org.quartz.impl;
//
//import java.text.ParseException;
//import java.util.Collections;
//import java.util.Date;
//import java.util.HashSet;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//
//import javax.management.Attribute;
//import javax.management.AttributeList;
//import javax.management.MalformedObjectNameException;
//import javax.management.ObjectName;
//import javax.management.openmbean.CompositeData;
//
//import org.quartz.JobDetail;
//import org.quartz.JobExecutionContext;
//import org.quartz.ListenerManager;
//import org.quartz.Scheduler;
//import org.quartz.SchedulerContext;
//import org.quartz.SchedulerException;
//import org.quartz.SchedulerMetaData;
//import org.quartz.Trigger;
//import org.quartz.UnableToInterruptJobException;
//import org.quartz.Trigger.TriggerState;
////import org.quartz.core.jmx.JobDetailSupport;
//import org.quartz.impl.matchers.GroupMatcher;
//import org.quartz.spi.JobFactory;
//import org.quartz.utils.Key;
//
///**
// * <p>
// * An implementation of the <code>Scheduler</code> interface that remotely
// * proxies all method calls to the equivalent call on a given <code>QuartzScheduler</code>
// * instance, via JMX.
// * </p>
// *
// * <p>
// * A user must create a subclass to implement the actual connection to the remote
// * MBeanServer using their application specific connector.
// * </p>
// * @see org.quartz.Scheduler
// * @see org.quartz.core.QuartzScheduler
// */
//public abstract class RemoteMBeanScheduler implements Scheduler {
//
//    /*
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     *
//     * Data members.
//     *
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     */
//
//    private ObjectName schedulerObjectName;
//
//    /*
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     *
//     * Constructors.
//     *
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     */
//
//    public RemoteMBeanScheduler() {
//    }
//
//    /*
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     *
//     * Properties.
//     *
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     */
//
//    /**
//     * Get the name under which the Scheduler MBean is registered on the
//     * remote MBean server.
//     */
//    protected ObjectName getSchedulerObjectName() {
//        return schedulerObjectName;
//    }
//
//    /**
//     * Set the name under which the Scheduler MBean is registered on the
//     * remote MBean server.
//     */
//    public void setSchedulerObjectName(String schedulerObjectName)  throws SchedulerException {
//        try {
//            this.schedulerObjectName = new ObjectName(schedulerObjectName);
//        } catch (MalformedObjectNameException e) {
//            throw new SchedulerException("Failed to parse Scheduler MBean name: " + schedulerObjectName, e);
//        }
//    }
//
//    /**
//     * Set the name under which the Scheduler MBean is registered on the
//     * remote MBean server.
//     */
//    public void setSchedulerObjectName(ObjectName schedulerObjectName)  throws SchedulerException {
//        this.schedulerObjectName = schedulerObjectName;
//    }
//
//
//    /*
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     *
//     * Abstract methods.
//     *
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     */
//
//    /**
//     * Initialize this RemoteMBeanScheduler instance, connecting to the
//     * remote MBean server.
//     */
//    public abstract void initialize() throws SchedulerException;
//
//    /**
//     * Get the given attribute of the remote Scheduler MBean.
//     */
//    protected abstract Object getAttribute(String attribute) throws SchedulerException;
//
//    /**
//     * Get the given attributes of the remote Scheduler MBean.
//     */
//    protected abstract AttributeList getAttributes(String[] attributes) throws SchedulerException;
//
//    /**
//     * Invoke the given operation on the remote Scheduler MBean.
//     */
////    protected abstract Object invoke(String operationName, Object[] params, String[] signature) throws SchedulerException;
//    protected abstract Object invoke(String operationName, Object[] params, String[] signature) throws SchedulerException;
//
//
//    /*
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     *
//     * Interface.
//     *
//     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     */
//
//    /**
//     * <p>
//     * Returns the name of the <code>Scheduler</code>.
//     * </p>
//     */
//    @Override
//    public String getSchedulerName() throws SchedulerException {
//        return (String)getAttribute("SchedulerName");
//    }
//
//    /**
//     * <p>
//     * Returns the instance Id of the <code>Scheduler</code>.
//     * </p>
//     */
//    @Override
//    public String getSchedulerInstanceId() throws SchedulerException {
//        return (String)getAttribute("SchedulerInstanceId");
//    }
//    @Override
//    public SchedulerMetaData getMetaData() throws SchedulerException {
//        AttributeList attributeList =
//            getAttributes(
//                new String[] {
//                    "SchedulerName",
//                    "SchedulerInstanceId",
//                    "StandbyMode",
//                    "Shutdown",
//                    "JobStoreClassName",
//                    "ThreadPoolClassName",
//                    "ThreadPoolSize",
//                    "Version",
//                    "PerformanceMetrics"
//                });
//
//        try {
//            return new SchedulerMetaData(
//                    (String)getAttribute(attributeList, 0).getValue(),
//                    (String)getAttribute(attributeList, 1).getValue(),
//                    getClass(), true, false,
//                    (Boolean)getAttribute(attributeList, 2).getValue(),
//                    (Boolean)getAttribute(attributeList, 3).getValue(),
//                    null,
//                    Integer.parseInt(((Map)getAttribute(attributeList, 8).getValue()).get("JobsExecuted").toString()),
//                    Class.forName((String)getAttribute(attributeList, 4).getValue()),
//                    false,
//                    false,
//                    Class.forName((String)getAttribute(attributeList, 5).getValue()),
//                    (Integer)getAttribute(attributeList, 6).getValue(),
//                    (String)getAttribute(attributeList, 7).getValue());
//        } catch (ClassNotFoundException e) {
//            throw new SchedulerException(e);
//        }
//    }
//
//    private Attribute getAttribute(AttributeList attributeList, int index) {
//        return (Attribute)attributeList.get(index);
//    }
//
//    /**
//     * <p>
//     * Returns the <code>SchedulerContext</code> of the <code>Scheduler</code>.
//     * </p>
//     */
//    @Override
//    public SchedulerContext getContext() throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    ///////////////////////////////////////////////////////////////////////////
//    ///
//    /// Schedululer State Management Methods
//    ///
//    ///////////////////////////////////////////////////////////////////////////
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public void start() throws SchedulerException {
//        invoke("start", new Object[] {}, new String[] {});
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public void startDelayed(int seconds) throws SchedulerException {
//        invoke("startDelayed", new Object[] {seconds}, new String[] {int.class.getName()});
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public void standby() throws SchedulerException {
//        invoke("standby", new Object[] {}, new String[] {});
//    }
//
//    /**
//     * Whether the scheduler has been started.
//     *
//     * <p>
//     * Note: This only reflects whether <code>{@link #start()}</code> has ever
//     * been called on this Scheduler, so it will return <code>true</code> even
//     * if the <code>Scheduler</code> is currently in standby mode or has been
//     * since shutdown.
//     * </p>
//     *
//     * @see #start()
//     * @see #isShutdown()
//     * @see #isInStandbyMode()
//     */
//    @Override
//    public boolean isStarted() throws SchedulerException {
//        return (Boolean) getAttribute("Started");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public boolean isInStandbyMode() throws SchedulerException {
//        return (Boolean)getAttribute("StandbyMode");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public void shutdown() throws SchedulerException {
//        // Have to get the scheduler name before we actually call shutdown.
//        String schedulerName = getSchedulerName();
//        invoke("shutdown", new Object[] {}, new String[] {});
//        SchedulerRepository.getInstance().remove(schedulerName);
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public void shutdown(boolean waitForJobsToComplete) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public boolean isShutdown() throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    @SuppressWarnings("unchecked")
//    public List<JobExecutionContext> getCurrentlyExecutingJobs() throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    ///////////////////////////////////////////////////////////////////////////
//    ///
//    /// Scheduling-related Methods
//    ///
//    ///////////////////////////////////////////////////////////////////////////
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public Date scheduleJob(JobDetail jobDetail, Trigger trigger)throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public Date scheduleJob(Trigger trigger) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public void addJob(JobDetail jobDetail, boolean replace) throws SchedulerException {
////        invoke(
////            "addJob",
////            new Object[] { JobDetailSupport.toCompositeData(jobDetail), replace },
////            new String[] { CompositeData.class.getName(), boolean.class.getName() });
////    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public void addJob(JobDetail jobDetail, boolean replace, boolean storeNonDurableWhileAwaitingScheduling) throws SchedulerException {
//        invoke(
//                "addJob",
//                new Object[] { JobDetailSupport.toCompositeData(jobDetail), replace , storeNonDurableWhileAwaitingScheduling},
//                new String[] { CompositeData.class.getName(), boolean.class.getName(), boolean.class.getName() });
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public boolean deleteJob(Key jobKey) throws SchedulerException {
//        return (Boolean)invoke(
//                "deleteJob",
//                new Object[] { jobKey.getName()/*, jobKey.getGroup()*/ },
//                new String[] { String.class.getName()/*, String.class.getName()*/ });
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public boolean unscheduleJob(Key triggerKey) throws SchedulerException {
//        return (Boolean)invoke(
//                "unscheduleJob",
//                new Object[] { triggerKey.getName()/*, triggerKey.getGroup()*/ },
//                new String[] { String.class.getName()/*, String.class.getName()*/ });
//    }
//
//    @Override
//    public boolean deleteJobs(List<Key> keys) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//    @Override
//    public void scheduleJobs(Map<JobDetail, Set<? extends Trigger>> triggersAndJobs, boolean replace) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//    @Override
//    public void scheduleJob(JobDetail jobDetail, Set<? extends Trigger> triggersForJob, boolean replace) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//    @Override
//    public boolean unscheduleJobs(List<Key> keys) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public Date rescheduleJob(Key triggerKey,Trigger newTrigger) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public void triggerJob(Key jobKey) throws SchedulerException {
////        triggerJob(jobKey, null);
////    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public void triggerJob(Key jobKey, JobDataMap data) throws SchedulerException {
////        throw new SchedulerException("Operation not supported for remote schedulers.");
////    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public void pauseTrigger(Key triggerKey) throws SchedulerException {
//        invoke(
//            "pauseTrigger",
//            new Object[] { triggerKey.getName()/*, triggerKey.getGroup()*/ },
//            new String[] { String.class.getName()/*, String.class.getName()*/ });
//    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public void pauseTriggers(GroupMatcher<TriggerKey> matcher) throws SchedulerException {
////        String operation = null;
////        switch (matcher.getCompareWithOperator()) {
////            case EQUALS:
////                operation = "pauseTriggerGroup";
////                break;
////            case CONTAINS:
////                operation = "pauseTriggersContaining";
////                break;
////            case STARTS_WITH:
////                operation = "pauseTriggersStartingWith";
////                break;
////            case ENDS_WITH:
////                operation = "pauseTriggersEndingWith";
////            case ANYTHING:
////                operation = "pauseTriggersAll";
////        }
////        if (operation != null) {
////            invoke(
////                    operation,
////                    new Object[] { matcher.getCompareToValue() },
////                    new String[] { String.class.getName() });
////        } else {
////            throw new SchedulerException("Unsupported GroupMatcher kind for pausing triggers: " + matcher.getCompareWithOperator());
////        }
////    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public void pauseJob(Key key) throws SchedulerException {
//        invoke(
//            "pauseJob",
//            new Object[] { key.getName()/*, jobKey.getGroup()*/ },
//            new String[] { String.class.getName()/*, String.class.getName()*/ });
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    public void pauseJobs(GroupMatcher<Key<?>> matcher) throws SchedulerException {
//        String operation = null;
//        switch (matcher.getCompareWithOperator()) {
//            case EQUALS:
//                operation = "pauseJobGroup";
//                break;
//            case STARTS_WITH:
//                operation = "pauseJobsStartingWith";
//                break;
//            case ENDS_WITH:
//                operation = "pauseJobsEndingWith";
//                break;
//            case CONTAINS:
//                operation = "pauseJobsContaining";
//            case ANYTHING:
//                operation = "pauseJobsAll";
//        }
//
//        invoke(
//                operation,
//                new Object[] { matcher.getCompareToValue() },
//                new String[] { String.class.getName() });
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public void resumeTrigger(Key triggerKey) throws SchedulerException {
//        invoke(
//            "resumeTrigger",
//            new Object[] { triggerKey.getName()/*, triggerKey.getGroup()*/ },
//            new String[] { String.class.getName()/*, String.class.getName()*/ });
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public void resumeTriggers(GroupMatcher<Key<?>> matcher) throws SchedulerException {
//        String operation = null;
//        switch (matcher.getCompareWithOperator()) {
//            case EQUALS:
//                operation = "resumeTriggerGroup";
//                break;
//            case CONTAINS:
//                operation = "resumeTriggersContaining";
//                break;
//            case STARTS_WITH:
//                operation = "resumeTriggersStartingWith";
//                break;
//            case ENDS_WITH:
//                operation = "resumeTriggersEndingWith";
//            case ANYTHING:
//                operation = "resumeTriggersAll";
//        }
//        if (operation != null) {
//            invoke(
//                    operation,
//                    new Object[] { matcher.getCompareToValue() },
//                    new String[] { String.class.getName() });
//        } else {
//            throw new SchedulerException("Unsupported GroupMatcher kind for resuming triggers: " + matcher.getCompareWithOperator());
//        }
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public void resumeJob(Key jobKey) throws SchedulerException {
//        invoke(
//            "resumeJob",
//            new Object[] { jobKey.getName()/*, jobKey.getGroup()*/ },
//            new String[] { String.class.getName()/*, String.class.getName()*/ });
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public void resumeJobs(final String triggerName) throws SchedulerException {
//        String operation = null;
////        switch (matcher.getCompareWithOperator()) {
////            case EQUALS:
////                operation = "resumeJobGroup";
////                break;
////            case STARTS_WITH:
////                operation = "resumeJobsStartingWith";
////                break;
////            case ENDS_WITH:
////                operation = "resumeJobsEndingWith";
////                break;
////            case CONTAINS:
////                operation = "resumeJobsContaining";
////            case ANYTHING:
////                operation = "resumeJobsAll";
////        }
//        if(null==triggerName || "".equals(triggerName.trim())){
//            operation = "resumeJobGroup";
//        }else{
//            operation = "resumeJobsAll";
//        }
////        invoke(operation, new Object[] { matcher.getCompareToValue() }, new String[] { String.class.getName() });
//        invoke(operation, new Object[] { triggerName }, new String[] { String.class.getName() });
//    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public void pauseAll() throws SchedulerException {
////        invoke(
////            "pauseAllTriggers",
////            new Object[] { },
////            new String[] { });
////    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public void resumeAll() throws SchedulerException {
////        invoke(
////            "resumeAllTriggers",
////            new Object[] { },
////            new String[] { });
////    }
////
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    @SuppressWarnings("unchecked")
////    public List<String> getJobGroupNames() throws SchedulerException {
////        return (List<String>)getAttribute("JobGroupNames");
////    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @SuppressWarnings("unchecked")
////    public Set<JobKey> getJobKeys(final String triggerName) throws SchedulerException {
////        List<JobKey> keys = (List<JobKey>)invoke("getJobNames",new Object[] { triggerName },new String[] { String.class.getName() });
////        return new HashSet<JobKey>(keys);
//////        if (matcher.getCompareWithOperator().equals(StringMatcher.StringOperatorName.EQUALS)) {
//////            List<JobKey> keys = (List<JobKey>)invoke("getJobNames",new Object[] { matcher.getCompareToValue() },new String[] { String.class.getName() });
//////            return new HashSet<JobKey>(keys);
//////        } else {
//////            throw new SchedulerException("Only equals matcher are supported for looking up JobKeys");
//////        }
////    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    @SuppressWarnings("unchecked")
//    public List<Trigger> getTriggersOfJob(Key jobKey) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @SuppressWarnings("unchecked")
//    public List<String> getTriggerGroupNames() throws SchedulerException {
//        return (List<String>)getAttribute("TriggerGroupNames");
//    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    @SuppressWarnings("unchecked")
////    public Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> matcher) throws SchedulerException {
////        throw new SchedulerException("Operation not supported for remote schedulers.");
////    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public JobDetail getJobDetail(Key jobKey) throws SchedulerException {
//        try {
//            return JobDetailSupport.newJobDetail((CompositeData)invoke(
//                    "getJobDetail",
//                    new Object[] { jobKey.getName()/*, jobKey.getGroup()*/ },
//                    new String[] { String.class.getName()/*, String.class.getName()*/ }));
//        } catch (ClassNotFoundException e) {
//            throw new SchedulerException("Unable to resolve job class", e);
//        }
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public Trigger getTrigger(Key triggerKey) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public boolean checkExists(Key jobKey) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public boolean checkTriggerExists(Key triggerKey) throws SchedulerException {
//        return (Boolean)invoke(
//                "checkExists",
//                new Object[] { triggerKey },
//                new String[] { Key.class.getName() });
//    }
//    @Override
//    public void clear() throws SchedulerException {
//        invoke(
//                "clear",
//                new Object[] {  },
//                new String[] {  });
//    }
//
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
//     * passing the <code>SchedulingContext</code> associated with this
//     * instance.
//     * </p>
//     */
//    @Override
//    public TriggerState getTriggerState(Key triggerKey) throws SchedulerException {
//        return TriggerState.valueOf((String)invoke(
//                "getTriggerState",
//                new Object[] { triggerKey.getName()/*, triggerKey.getGroup()*/ },
//                new String[] { String.class.getName()/*, String.class.getName()*/ }));
//    }
//
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    public void resetTriggerFromErrorState(TriggerKey triggerKey) throws SchedulerException {
////        invoke(
////            "resetTriggerFromErrorState",
////            new Object[] { triggerKey.getName(), triggerKey.getGroup() },
////            new String[] { String.class.getName(), String.class.getName() });
////    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public void addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers) throws SchedulerException {
////        invoke(
////            "addCalendar",
////            new Object[] { calName, calendar, replace, updateTriggers },
////            new String[] { String.class.getName(),Calendar.class.getName(), boolean.class.getName(), boolean.class.getName() });
////    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public boolean deleteCalendar(String calName) throws SchedulerException {
////        invoke("deleteCalendar",
////                new Object[] { calName },
////                new String[] { String.class.getName() });
////        return true;
////    }
//
////    /**
////     * <p>
////     * Calls th0e equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    public Calendar getCalendar(String calName) throws SchedulerException {
////        throw new SchedulerException("Operation not supported for remote schedulers.");
////    }
//
////    /**
////     * <p>
////     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>,
////     * passing the <code>SchedulingContext</code> associated with this
////     * instance.
////     * </p>
////     */
////    @Override
////    @SuppressWarnings("unchecked")
////    public List<String> getCalendarNames() throws SchedulerException {
////        return (List<String>)getAttribute("CalendarNames");
////    }
//
//    /**
//     * @see org.quartz.Scheduler#getPausedTriggerGroups()
//     */
//    @SuppressWarnings("unchecked")
//    public Set<String> getPausedTriggerGroups() throws SchedulerException {
//        return (Set<String>)getAttribute("PausedTriggerGroups");
//    }
//
//    ///////////////////////////////////////////////////////////////////////////
//    ///
//    /// Other Methods
//    ///
//    ///////////////////////////////////////////////////////////////////////////
//
//    /**
//     * <p>
//     * Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
//     * </p>
//     */
//    @Override
//    public ListenerManager getListenerManager() throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//    /**
//     * @see org.quartz.Scheduler#interrupt(JobKey)
//     */
//    @Override
//    public boolean interrupt(Key jobKey) throws UnableToInterruptJobException  {
//        try {
//            return (Boolean)invoke(
//                    "interruptJob",
//                    new Object[] { jobKey.getName()/*, jobKey.getGroup()*/ },
//                    new String[] { String.class.getName()/*, String.class.getName()*/ });
//        } catch (SchedulerException se) {
//            throw new UnableToInterruptJobException(se);
//        }
//    }
//    @Override
//    public boolean interrupt(String fireInstanceId) throws UnableToInterruptJobException {
//        try {
//            return (Boolean)invoke(
//                    "interruptJob",
//                    new Object[] { fireInstanceId },
//                    new String[] { String.class.getName() });
//        } catch (SchedulerException se) {
//            throw new UnableToInterruptJobException(se);
//        }
//    }
//
//    /**
//     * @see org.quartz.Scheduler#setJobFactory(org.quartz.spi.JobFactory)
//     */
//    @Override
//    public void setJobFactory(JobFactory factory) throws SchedulerException {
//        throw new SchedulerException("Operation not supported for remote schedulers.");
//    }
//
//}
